import GameTaskData from "../scene/game_task_game";
import GameTaskWx from "../scene/game_task_wx";
import data from "./cache_data";
import { Col } from "./data_ext";
import { GameConfig } from "./game_config";
import GameTask from "./game_task";
import { PreloadConfig } from "./loader";
import Macro from "./macro";
import Utils from "./utils";

const { ccclass, property } = cc._decorator;

/**
 * PersistNode。
 * 
 * 常驻节点，会在场景运行时第一个执行。
 * 可以把一些不继承cc.Component的代码初始化放到onLoad中。
 */
@ccclass
export default class PersistNode extends cc.Component {
    @property(cc.Prefab)
    canvasHPrefab: cc.Prefab = null;
    @property(cc.Prefab)
    canvasVPrefab: cc.Prefab = null;

    @property(cc.JsonAsset)
    gameConfigDev: cc.JsonAsset = null;

    onDestroy() {
    }
    async onLoad() {
    }
    async start() {
        let gameConfigData = null;
        if (Macro.BUILD_TARGET == "dev") {
            gameConfigData = this.gameConfigDev.json;
        }
        else {
            if (window["gameConfig"]) {
                gameConfigData = window["gameConfig"];
            }
            else {
                //根据地址参数载入游戏配置
                let gameConfigKey = Utils.parseUrlParam().gameConf;
                if (!gameConfigKey) {
                    console.error("缺失gameConf参数");
                    return;
                }
                let gameConfigUrl = `games/${gameConfigKey}/config.json`;
                try {
                    let res = await fetch(gameConfigUrl);
                    let gameConfigDataStr = await res.text();
                    gameConfigData = JSON.parse(gameConfigDataStr);
                }
                catch (e) {
                    console.error("游戏配置下载或解析失败", e);
                    return;
                }
            }
        }

        data.gameConfig = new GameConfig();
        data.gameConfig.assignFromJSON(gameConfigData);

        {//创建CANVAS
            let canvasNode = null;
            switch (data.gameConfig.screen) {
                case "Landscape":
                    canvasNode = cc.instantiate(this.canvasHPrefab);
                    break;
                case "Vertical":
                    canvasNode = cc.instantiate(this.canvasVPrefab);
                    break;
                default:
                    console.error("配置缺少screen参数");
                    return;
                    break;
            }
            this.node.parent.addChild(canvasNode);

            Utils.game.startPageName = data.gameConfig.defaultStartPage;

            //准备资源(载入部分)
            let remotePreloadConfigCol: Col<PreloadConfig> = {};
            //开始载入游戏
            await this.loadGame(remotePreloadConfigCol);

            if (data.gameConfig.wxConfig && data.gameConfig.wxConfig.enabled) {
                let taskWx = Utils.game.addGameTask(GameTaskWx);
                taskWx.isSync = false;
                taskWx.isBeforeGame = false;
            }

            //加入任务
            data.gameConfig.gameTaskList.forEach(name => {
                let cls = <new () => GameTask>cc.js.getClassByName(name);
                if (cls) {
                    let gameTask = Utils.game.addGameTask(cls);
                    gameTask.isSync = true;
                    gameTask.isBeforeGame = true;
                }
                else {
                    console.warn("找不到任务:", name);
                }
            });

            //运行所有任务
            Utils.game.addGameTask(GameTaskData);

            try {
                await Utils.game.runAllGameTask();
            }
            catch (e) {
                console.error("运行任务失败：", e);
                return;
            }

            //开始游戏
            Utils.game.startGame();
        }
    }
    async loadGame(remotePreloadConfigCol: Col<PreloadConfig>) {
        //准备
        await Utils.loader.init(data.gameConfig.bundleConfigCol, remotePreloadConfigCol);

        //载入box_loading
        let boxLoadingName = data.gameConfig.loading.boxLoadingName || "box_loading";
        //覆盖默认LOADING界面。
        await Utils.loader.loadAsset<cc.Prefab>(`boxes/${boxLoadingName}.prefab`, "boxes", "cc.Prefab");
        Utils.game.resPushBox(boxLoadingName);

        //main.js splash fadeout
        if (Macro.BUILD_TARGET !== "dev") {
            //@ts-ignore
            LoadingDom && LoadingDom.onFinish();
        }

        await Utils.loader.preload();
    }
};